home *** CD-ROM | disk | FTP | other *** search
- /* Simple sample player for AHI using the low-level API.
- Hardcoded sample names.
-
- This software is Public Domain. */
-
- #include <devices/ahi.h>
- #include <exec/exec.h>
- #include <proto/ahi.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
-
- #define USE_AHI_V4 TRUE
-
- #define CHANNELS 2
- #define MAXSAMPLES 16
-
- #define INT_FREQ 50
-
- char *ID = "$VER: SimplePlay 1.3 (23.4.97)\r\n";
-
- APTR samples[MAXSAMPLES] = { 0 };
-
- struct {
- BOOL FadeVolume;
- Fixed Volume;
- sposition Position;
- } channelstate[CHANNELS];
-
- struct {
- struct AHIEffDSPMask mask;
- UBYTE mode[CHANNELS];
- } maskeffect = {0};
- struct AHIDSPEcho echoeffect = {0};
-
- struct Library *AHIBase;
- struct MsgPort *AHImp = NULL;
- struct AHIRequest *AHIio = NULL;
- BYTE AHIDevice = -1;
- struct AHIAudioCtrl *actrl = NULL;
-
- LONG mixfreq = 0;
-
- /* Prototypes */
-
- BOOL OpenAHI(void);
- void CloseAHI(void);
- BOOL AllocAudio(void);
- void FreeAudio(void);
- UWORD LoadSample(unsigned char * , ULONG );
- void UnloadSample(UWORD );
- int main(void);
-
- /******************************************************************************
- ** PlayerFunc *****************************************************************
- ******************************************************************************/
-
- __asm __interrupt __saveds static void PlayerFunc(
- register __a0 struct Hook *hook,
- register __a2 struct AHIAudioCtrl *actrl,
- register __a1 APTR ignored) {
-
- int i;
-
- for(i = 0; i < CHANNELS; i++) {
-
- if(channelstate[i].FadeVolume) {
-
- channelstate[i].Volume = (channelstate[i].Volume * 90) / 100; // Fade volume
-
- if(channelstate[i].Volume == 0) {
- channelstate[i].FadeVolume = FALSE;
- }
-
- AHI_SetVol(i, channelstate[i].Volume, channelstate[i].Position,
- actrl, AHISF_IMM);
- }
- }
- return;
- }
-
- struct Hook PlayerHook = {
- 0,0,
- (ULONG (* )()) PlayerFunc,
- NULL,
- NULL,
- };
-
- /******************************************************************************
- **** OpenAHI ******************************************************************
- ******************************************************************************/
-
- /* Open the device for low-level usage */
-
- BOOL OpenAHI(void) {
-
- if(AHImp = CreateMsgPort()) {
- if(AHIio = (struct AHIRequest *)CreateIORequest(
- AHImp,sizeof(struct AHIRequest))) {
-
- #if USE_AHI_V4
- AHIio->ahir_Version = 4;
- #else
- AHIio->ahir_Version = 2;
- #endif
-
- if(!(AHIDevice = OpenDevice(AHINAME, AHI_NO_UNIT,
- (struct IORequest *) AHIio,NULL))) {
- AHIBase = (struct Library *) AHIio->ahir_Std.io_Device;
- return TRUE;
- }
- }
- }
- FreeAudio();
- return FALSE;
- }
-
-
- /******************************************************************************
- **** CloseAHI *****************************************************************
- ******************************************************************************/
-
- /* Close the device */
-
- void CloseAHI(void) {
-
- if(! AHIDevice)
- CloseDevice((struct IORequest *)AHIio);
- AHIDevice=-1;
- DeleteIORequest((struct IORequest *)AHIio);
- AHIio=NULL;
- DeleteMsgPort(AHImp);
- AHImp=NULL;
- }
-
-
- /******************************************************************************
- **** AllocAudio ***************************************************************
- ******************************************************************************/
-
- /* Ask user for an audio mode and allocate it */
-
- BOOL AllocAudio(void) {
- struct AHIAudioModeRequester *req;
- BOOL rc = FALSE;
-
- req = AHI_AllocAudioRequest(
- AHIR_PubScreenName, NULL,
- AHIR_TitleText, "Select a mode and rate",
- AHIR_DoMixFreq, TRUE,
- TAG_DONE);
-
- if(req) {
- if(AHI_AudioRequest(req, TAG_DONE)) {
- actrl = AHI_AllocAudio(
- AHIA_AudioID, req->ahiam_AudioID,
- AHIA_MixFreq, req->ahiam_MixFreq,
- AHIA_Channels, CHANNELS,
- AHIA_Sounds, MAXSAMPLES,
- AHIA_PlayerFunc, &PlayerHook,
- AHIA_PlayerFreq, INT_FREQ<<16,
- AHIA_MinPlayerFreq, INT_FREQ<<16,
- AHIA_MaxPlayerFreq, INT_FREQ<<16,
- TAG_DONE);
- if(actrl) {
- // Get real mixing frequency
- AHI_ControlAudio(actrl, AHIC_MixFreq_Query, &mixfreq, TAG_DONE);
- rc = TRUE;
- }
- }
- AHI_FreeAudioRequest(req);
- }
- return rc;
- }
-
-
- /******************************************************************************
- **** FreeAudio ****************************************************************
- ******************************************************************************/
-
- /* Release the audio hardware */
-
- void FreeAudio() {
-
- AHI_FreeAudio(actrl);
- actrl = NULL;
- }
-
- /******************************************************************************
- **** LoadSample ***************************************************************
- ******************************************************************************/
-
- /* Load a (raw) 8 or 16 bit sample from disk. The sample ID is returned
- (or AHI_NOSOUND on error). */
-
- UWORD LoadSample(char *filename, ULONG type) {
- struct AHISampleInfo sample;
- APTR *samplearray = samples;
- UWORD id = 0, rc = AHI_NOSOUND;
- BPTR file;
-
- // Find a free sample slot
-
- while(*samplearray) {
- id++;
- samplearray++;
- if(id >= MAXSAMPLES) {
- return AHI_NOSOUND;
- }
- }
-
- file = Open(filename, MODE_OLDFILE);
-
- if(file) {
- int length;
-
- Seek(file, 0, OFFSET_END);
- length = Seek(file, 0, OFFSET_BEGINNING);
- *samplearray = AllocVec(length, MEMF_PUBLIC);
- if(*samplearray) {
- Read(file, *samplearray, length);
-
- sample.ahisi_Type = type;
- sample.ahisi_Address = *samplearray;
- #if USE_AHI_V4
- sample.ahisi_Length = length / AHI_SampleFrameSize(type);
- #else
- sample.ahisi_Length = length / (type == AHIST_M16S ? 2 : 1);
- #endif
- if(! AHI_LoadSound(id, AHIST_SAMPLE, &sample, actrl)) {
- rc = id;
- }
- }
- Close(file);
- }
- return rc;
- }
-
-
- /******************************************************************************
- **** UnloadSample *************************************************************
- ******************************************************************************/
-
- void UnloadSample(UWORD id) {
-
- AHI_UnloadSound(id, actrl);
- FreeVec(samples[id]);
- samples[id] = NULL;
- }
-
- /******************************************************************************
- **** main *********************************************************************
- ******************************************************************************/
-
- int main() {
- UWORD sample, ahem, louise;
- int i;
-
- for(i = 0; i < CHANNELS; i++) {
- channelstate[i].FadeVolume = FALSE;
- }
-
- if(OpenAHI()) {
- if(AllocAudio()) {
- ahem = LoadSample("Projekt:ahi/samples/ASS-14.sb", AHIST_M8S);
- louise = LoadSample("Projekt:ahi/samples/LouiseR.sw", AHIST_M16S);
- if((ahem != AHI_NOSOUND) && (louise != AHI_NOSOUND)) {
-
- // Start feeding samples to sound hardware
- if(!(AHI_ControlAudio(actrl,
- AHIC_Play, TRUE,
- TAG_DONE)))
- {
-
- #if USE_AHI_V4
- Printf("Playing two samples, one with echo and one without.\n");
-
- // Turn on echo on channel 1
- // No error checking here, but you should do that.
- maskeffect.mask.ahie_Effect = AHIET_DSPMASK;
- maskeffect.mask.ahiedm_Channels = CHANNELS;
- maskeffect.mode[0] = AHIEDM_DRY;
- maskeffect.mode[1] = AHIEDM_WET;
- AHI_SetEffect( &maskeffect, actrl );
-
- echoeffect.ahie_Effect = AHIET_DSPECHO;
- echoeffect.ahiede_Delay = mixfreq / 4; // 250 ms
- echoeffect.ahiede_Feedback = 0x8000; // 50 %
- echoeffect.ahiede_Mix = 0x10000; // 100% and...
- echoeffect.ahiede_Cross = 0; // ...0% gives faster echo code.
- AHI_SetEffect( &echoeffect, actrl );
-
- AHI_Play(actrl,
- // A forever-looping sample on channel 0
- AHIP_BeginChannel, 0,
- AHIP_Freq, 17640,
- AHIP_Vol, 0x10000,
- AHIP_Pan, 0xc000,
- AHIP_Sound, louise,
- AHIP_EndChannel, NULL,
-
- // A oneshot sample on channel 1
- AHIP_BeginChannel, 1,
- AHIP_Freq, 22254,
- AHIP_Vol, 0x10000,
- AHIP_Pan, 0x4000,
- AHIP_Sound, ahem,
- AHIP_LoopSound, AHI_NOSOUND,
- AHIP_EndChannel, NULL,
-
- TAG_DONE);
- #else
- Printf("Playing two samples.\n");
-
- // A forever-looping sample on channel 0
- AHI_SetFreq(0, 17640, actrl, AHISF_IMM);
- AHI_SetVol(0, 0x10000, 0xc000, actrl, AHISF_IMM);
- AHI_SetSound(0, louise, 0, 0, actrl, AHISF_IMM);
-
- // A oneshot sample on channel 1
- AHI_SetFreq(1, 22254, actrl, AHISF_IMM);
- AHI_SetVol(1, 0x10000, 0x4000, actrl, AHISF_IMM);
- AHI_SetSound(1, ahem, 0, 0, actrl, AHISF_IMM);
- AHI_SetSound(1, AHI_NOSOUND, 0, 0, actrl, 0);
- #endif
- channelstate[0].Volume = 0x10000;
- channelstate[0].Position = 0xc000;
- channelstate[1].Volume = 0x10000;
- channelstate[1].Position = 0x4000;
-
- // Wait 5 seconds
-
- Delay(5 * TICKS_PER_SECOND);
-
- #if USE_AHI_V4
- Printf("Turning on echo on channel 0.\n");
-
- // Turn on echo on channel 0, turn off channel 1
- // No error checking here, but you should do that.
- maskeffect.mode[0] = AHIEDM_WET;
- maskeffect.mode[1] = AHIEDM_DRY;
- AHI_SetEffect( &maskeffect, actrl );
- #endif
-
- // Wait 5 seconds
-
- Delay(5 * TICKS_PER_SECOND);
-
- Printf("Fading away the sound on channel 0... ");
- Flush(Output());
-
- // Fade away channel 0
-
- channelstate[0].FadeVolume = TRUE;
-
- while(channelstate[0].FadeVolume) {
- Delay(1);
- }
-
- Printf("Done!\n");
-
- // Wait a sec...
-
- Delay(TICKS_PER_SECOND);
-
- // Stop sounds
- AHI_ControlAudio(actrl,
- AHIC_Play, FALSE,
- TAG_DONE);
-
-
- #if USE_AHI_V4
- // Cancel effects
-
- maskeffect.mask.ahie_Effect = AHIET_DSPMASK | AHIET_CANCEL;
- AHI_SetEffect( &maskeffect, actrl );
-
- echoeffect.ahie_Effect = AHIET_DSPECHO | AHIET_CANCEL;
- AHI_SetEffect( &echoeffect, actrl );
- #endif
-
- }
- }
-
- // Ask AHI to unload all loaded samples and free the memory for them
- for(sample = 0; sample < MAXSAMPLES; sample++) {
- UnloadSample(sample);
- }
-
- }
- FreeAudio();
- }
- CloseAHI();
-
- return 0;
- }
-